/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * * * * * * * * * * * * * 请求库封装 * * * * * * * * * * * * * * *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
import axios, {AxiosInstance, AxiosResponse} from "axios"
import store from "@/store/index"
import appStore from "@/store/app"
import guardStore from "@/apps/admin/store/guard"
import {getTimestamp} from "@/units/time";
import {useErrorDialog} from "@/hooks/DialogMsg";
import bus from "@/units/bus";

/**
 * 载入全局配置
 */
const astore = appStore(store)

/**
 * 创建请求实例
 */
const Instance: AxiosInstance = axios.create()

/**
 * 前置拦截器
 */
Instance.interceptors.request.use(req => {
    const gstore = guardStore(store)
    req.timestramp = getTimestamp('long')
    req.headers['X-Requested-With'] = 'XMLHttpRequest'//用来区分是ajax请求还是普通http请求
    req.headers['Auth-Token'] = gstore.token ? gstore.token : ''//授权凭证请求头
    return req
})


// @ts-ignore axio后置拦截器
Instance.interceptors.response.use(function (res: AxiosResponse) {
    let timestramp = getTimestamp('long') - res.config.timestramp
    //200状态码,请求失败了
    if (res.status !== 200) {
        if (res.config?.tips === true) {
            useErrorDialog("数据请求失败,请检查网络是否正常!").then()
        }
        return {code: 404, msg: "数据请求失败,请检查网络是否正常!", timestramp: timestramp}
    }
    //下面都是200状态码,请求成功了
    if (res.data instanceof Object && res.data.code && res.data.msg) {//封装的接口响应数据结构
        const HttpData = {code: res.data.code, msg: res.data.msg, data: res.data.data, timestramp: timestramp}
        if (HttpData.code === 200) {
            return HttpData
        } else if (HttpData.code === 403 || HttpData.code === 402) {//没登陆或登录已过期
            useErrorDialog(HttpData.msg).then(() => bus.emit('user-logout', undefined))
        } else if (res.config.tips === true) {
            useErrorDialog(HttpData.msg).then()
        }
        return HttpData
    }
    //非封装接口结构,组装且返回原始数据
    return {code: 200, msg: "请求数据", data: res.data, timestramp: timestramp}
}, function (err) {
    let timestramp = getTimestamp() - err.config.timestramp
    if (err.config?.tips === true) {
        useErrorDialog("数据请求失败,请检查网络是否正常!").then()
    }
    return {code: 404, msg: "数据请求失败,请检查网络是否正常!", timestramp: timestramp}
})


/**
 * 获取请求实例
 * @constructor
 */
export function getInstance() {
    return Instance
}

/**
 * 导出请求
 * @param url 请求地址
 * @param data 请求数据
 * @param method 请求方法
 * @param options  是否提示
 * @return {Promise<axios.AxiosResponse<any>>}
 */
export default function (url: string, data = {}, method: "GET" | "POST" = 'GET', options: { tips?: boolean, timeout?: number } = {tips: true, timeout: 15000}): Promise<any> {
    //判断url是否是以astore.ext.base_api为开头,是的化删除url开头的astore.ext.base_api部分
    if (url.startsWith(astore.ext.base_api)) {
        url = url.substring(astore.ext.base_api.length)
    }
    return Instance({
        baseURL: astore.ext.base_api,
        timeout: 15000,//超时时间15秒
        method: method,
        url: url,
        params: method === 'GET' ? data : {},
        data: data,
        timestramp: 0,
        ...options,
        tips: options.tips !== false
    })
}